<?php
/**
 * shSession est dédié à la gestion de la session utilisateur
 * /!\ Elle est ouverte dès l'arrivée sur l'application (même hors login)
 *
 * @category librairies
 * @package sh
 *
 * @author Mickaël CASTANHEIRO
 * @version 1.0
 */
class shSession extends shBase {
    /**
     * @access private
     * @var shSession
     */
    private static $instance;

    /**@#+
     * @access protected
     */
    /**
     * Utilisateur connecté
     * @var <boolean>
     */
    protected $authenticated;

    /**
     * Id unique
     * @var <integer>
     */
    protected $id;

    /**
     * Identifiant de connexion
     * @var <string>
     */
    protected $identifiant;

    /**
     * Mot de passe CRYPTE
     * @var <string>
     */
    protected $motdepasse;

    /**
     * Adresse email
     * @var <string>
     */
    protected $email;
    /**@#-*/

    /**
     * Droits d'accès aux actions
     * @access protected
     * @var array
     */
    protected $authorizations;

    /**
     * Objet
     */


    /**
     * Accès au singleton de la classe
     *
     * Génère le singleton de la classe si cela n'a pas été fait.
     * Retourne simplement l'instance unique sinon
     *
     * @return <shSession> Instance unique de la classe
     */
    public function __instance() {
	if ( !(self::$instance instanceof shSession) ) {
	    //Création de la session
	    if ( !empty($_SESSION['shSession']) ) {
		self::$instance = unserialize($_SESSION['shSession']);
	    }
	    else {
		self::$instance = new shSession();
	    }
	}
	return self::$instance;
    }



    /**
     * Constructeur de la classe
     *
     * @access private
     * @return shSession Instance crée
     */
    private function __construct() {
	$this->authenticated = false;

	if ( !empty($_COOKIE['shCookieIdentifiant']) AND !empty($_COOKIE['shCookieMotdepasse']) )
	    $this->login($_COOKIE['shCookieIdentifiant'], $_COOKIE['shCookieMotdepasse'], true);
    }


    /**
     * Modifie les droits d'un module/action/requete
     * @param <string> Module
     * @param <string> Action
     * @param <string> Requete
     * @param <boolean> Accès autorisé ou non
     */
    public function setAuthorization($_module, $_action=null, $_request=null) {
	if ( !empty($_module) AND !empty($_action) AND !empty($_request) ) {
	    $this->authorizations->{$_module}->{$_action}->{$_request}->{'.access'} = true;
	}
	
	elseif ( !empty($_module) AND !empty($_action) ) {
	    $this->authorizations->{$_module}->{$_action}->{'.access'} = true;
	}

	elseif ( !empty($_module) ) {
	    $this->authorizations->{$_module}->{'.access'} = true;
	}
    }

    /**
     * Indique si l'on possède le droit de visiter un module/action/requete     *
     * @param <string> Module auquel s'applique le droit
     * @param <string> Action à laquelle s'applique le droit
     * @param <string> Requête à laquelle s'applique le droit
     */
    public function isAuthorization($_module, $_action=null, $_request=null) { 
	if ( !empty($_module) AND !empty($_action) AND !empty($_request) ) {
	    return ( isset($this->authorizations->{$_module}->{$_action}->{$_request}->{'.access'}) ) ?
		$this->authorizations->{$_module}->{$_action}->{$_request}->{'.access'} :
		false;
	}

	elseif ( !empty($_module) AND !empty($_action) ) {
	    return ( isset($this->authorizations->{$_module}->{$_action}->{'.access'}) ) ?
		$this->authorizations->{$_module}->{$_action}->{'.access'} :
		false;
	}

	elseif ( !empty($_module) ) {
	    return ( isset($this->authorizations->{$_module}->{'.access'}) ) ?
		$this->authorizations->{$_module}->{'.access'} :
		false;
	}
    }


    /**
     * Fonction de login
     * @param <integer> Id de la table user
     * @param <string> Mot de passe crypté
     */
    public function login($_id, $_motdepasse, $_saveCookie=false) {
	// Sélection de l'utilisateur
	if ( $user = shSGBD::selectOne( 'SELECT user.id, user.identifiant, user.motdepasse, user.email '.
					'FROM user '.
					'WHERE user.id=:identifiant '.
					'AND user.motdepasse=:motdepasse',
	array(':identifiant' => $_id, ':motdepasse' => $_motdepasse)) ) {

	    $this->authenticated = true;
	    $this->id = $user->id;
	    $this->identifiant = $user->identifiant;
	    $this->motdepasse = $user->motdepasse;
	    $this->email = $user->email;

	    // Gestion des droits : Charge les droits auxquels on PEUT accéder
	    $droits = shSGBD::select(
		'SELECT droit.id, droit.module, droit.action, droit.request '.
		' FROM droit '.
		' INNER JOIN droit_profil ON droit.id=droit_profil.id_droit '.
		' INNER JOIN profil ON droit_profil.id_profil=profil.id '.
		' INNER JOIN profil_user ON profil.id=profil_user.id_profil '.
		' INNER JOIN user ON profil_user.id_user=user.id '.
		' WHERE user.id=? ',
		array($this->id)
	    );
	
	    foreach($droits AS $droit) {
		$this->setAuthorization($droit->module, $droit->action, $droit->request);
	    }
	}

	// Sauvegarde de la session
	$this->saveSession();

	// Sauvegarde des cookies si nécessaire
	if ( $_saveCookie )
	    $this->saveCookie();
    }

    /**
     * Sauvegarde de la session dans le tableau session
     */
    public function saveSession() {
	$_SESSION['shSession'] = serialize($this);
    }

    /**
     * Sauvegarde de l'identifiant et du mot de passe dans les cookies
     */
    public function saveCookie() {
	if ( !empty($this->id) AND !empty($this->motdepasse) ) {
	    $expire = $_SERVER['REQUEST_TIME'] + 30*24*3600; // expire dans 30 jours
	    setCookie('shCookieIdentifiant', $this->id, $expire, '/');
	    setCookie('shCookieMotdepasse', $this->motdepasse, $expire, '/');
	}
    }

    public function unsaveSessionAndCookie() {
	$this->authenticated = false; 
	setCookie('shCookieIdentifiant', '', $_SERVER['REQUEST_TIME']-42000, '/');
	setCookie('shCookieMotdepasse', '', $_SERVER['REQUEST_TIME']-42000, '/');
	unset($_COOKIE['shCookieIdentifiant']);
	unset($_COOKIE['shCookieMotdepasse']);
	self::$instance = new shSession;
	unset($_SESSION);
	session_destroy();
    }
}

?>